
package x.trident.core.micro.core.feign;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import feign.Response;
import feign.codec.ErrorDecoder;
import lombok.extern.slf4j.Slf4j;
import x.trident.core.micro.api.exception.MicroException;
import x.trident.core.micro.api.exception.enums.FeignExceptionEnum;

import java.io.IOException;

/**
 * feign错误解码器（为了feign接收到错误的返回）
 *
 * @author Seven
 * @date 2021/4/20 23:14
 */
@Slf4j
public class TridentFeignErrorDecoder implements ErrorDecoder {

    @Override
    public Exception decode(String methodKey, Response response) {

        // 1. 响应为空的情况
        if (response == null || response.body() == null) {
            return new MicroException(FeignExceptionEnum.REMOTE_SERVICE_ERROR, "未知异常-响应为空");
        }

        // 2. 解析出来ResponseBody内容，如果body解析异常则直接抛出MicroException
        String responseBody;
        try {
            if (response.status() == 404) {
                return new MicroException(FeignExceptionEnum.REMOTE_SERVICE_NULL);
            }
            responseBody = IoUtil.read(response.body().asInputStream(), "UTF-8");
        } catch (IOException e) {
            return new MicroException(FeignExceptionEnum.REMOTE_IO_ERROR);
        }

        // 3. 解析出来ResponseBody后，用json反序列化
        JSONObject jsonObject = JSON.parseObject(responseBody);
        if (log.isDebugEnabled()) {
            log.debug("FeignErrorDecoder收到错误响应结果：" + responseBody);
        }

        // 4. 获取有效信息
        String message = jsonObject.getString("message");
        if (StrUtil.isEmpty(message)) {
            message = "未知错误-message为空";
        }

        return new MicroException(FeignExceptionEnum.REMOTE_SERVICE_ERROR, message);
    }

}